home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1996 April
/
CHIP 1996 aprilis (CD06).zip
/
CHIP_CD06.ISO
/
hypertxt.arj
/
92
/
STRING.CD
< prev
next >
Wrap
Text File
|
1995-09-14
|
5KB
|
128 lines
@VStringek összehasonlítása@N
Programok az olvasótól az olvasóhoz -- ennek a mottónak
a szellemében választjuk ki hónapról-hónapra a beérkezett
küldeményekbôl a hasznos programlistákat. Sajnos egyelôre
még csak a CHIP német kiadásának szerkesztôségébe beérkezett
levelek közül válogathatunk, de várjuk a magyar olvasók
leveleit is.
Ha egy adathalmazban -- például egy címállományban --
egy bizonyos szót meg akarunk találni, akkor a hibásan
rögzített adatok -- ha mondjuk a ""Molnár"-t ""Nolnár"-nak
írták -- miatt a keresés sokszor eredménytelen. Kiutat kínál
e helyzetbôl az itt közölt HASONLO Turbo Pascal függvény
(lásd a mellékelt listát). Két string összehasonlítására
szolgál, és egy olyan értéket ad meg, amely azt jelzi, hogy
a két string mennyire hasonlít egymáshoz. Ha megegyeznek,
akkor az érték 0, egyébként minden eltérésnél 1-gyel
növekszik az érték (túl sok, túl kevés vagy hibás a betû).
Például a következô stringek esetén ezek az eredmények
adódnak:
hasonlo('Computer','Computer') = 0
hasonlo('Computer','Cmputeer') = 2
hasonlo('Computer','Kombute') = 3
hasonlo('Computer','ootper') = 4
Mint látható, a meglehetôsen hibás stringek is még
viszonylag kis értéket szolgáltatnak, így például 1-es
értékû hasonlóság esetén a példabeli Nollár urat még meg
lehetne találni. Ezt a rutint szinte megérintette a
mesterséges intelligencia fuvallata...
A megvalósítás alapját lényegében a Turbo Pascal
rekurziós képessége adja. Ha a stringek különbözô
hosszúságúak, akkor a rövidebb minden lehetséges módon
kiegészül #0-val, s ennek során mindig végrehajtódik az
összehasonlítás, miközben feltételezzük, hogy azok a
kombinációk szolgáltatják a legnagyobb valószínûséggel a
keresett eredményt, amelyeknél a legnagyobb valószínûség
megállapításra kerül. Azért #0-val történik a feltöltés,
mert ez az érték a Turbo Pascal programokban közönséges
esetben nem fordul elô, s ezért mindig az egyenlôtlenségnek
megfelelô értéket adja.
Különleges problémát jelent összehasonlításkor, ha a két
string el van tolva egymáshoz képest (például Computer és
omputero), hiszen itt a byte-onkénti összehasonlítás
semmiféle hasonlóságot nem találna. A következô eljárás
segít ilyenkor, amely felismeri mindkét irányban az egy
hellyel való eltolódásokat: egymásután három lépésben
töröljük azokat az azonos karaktereket, amelyek ugyanazon a
helyen állnak vagy egy hellyel jobbra illetve balra el
vannak tolva.
A ("computer","cmpllute") füzérpárból elôször
("omputer","mpllute") lesz, majd ("outer","llute") és végül
("or","ll"). A hasonlóság 2+2=4. Az elsô összeadandó a
megmaradó betûk számának felel meg, míg a második azt adja
meg, hogy hány átlós összehasonlítás során talált a program
megfelelést. A törlések sorrendjének csak néhány speciális
esetben van olyan hatása, hogy az eredmények kissé eltérnek
egymástól.
Végül néhány szó a számítás idejérôl: ha a stringek
hossza erôsen eltér, akkor a #0-val való feltöltések
lehetôségének nagy száma miatt a számítási idô igencsak
megnô, ezért ezt a mûveletet csak viszonylag kis különbségek
(öt karakternél kevesebb) esetén ajánlatos használni.
@KFrank Langlotz@N
@V1.lista@N
program hasonlo_teszt;
function hasonlo(a,b:string):byte;
var i,ered1,ered2:byte;
csere,bcopy:string;
valtozas:boolean;
begin
ered1:=255;
if length(a)<length(b) then begin
csere:=a;
a:=b;
b:=csere;
end;
if length(a)>length(b) then
for i:=1 to length(a) do begin
bcopy:=b;
insert(#0,bcopy,i);
ered2:=hasonlo(a,bcopy);
if ered2<ered1 then ered1:=ered2;
end
else begin
ered2:=0;
i:=1;
while i<=length(a) do if a[i]=b[i] then begin
delete(a,i,1);
delete(b,i,1);
end else i:=i+1;
i:=2;
valtozas:=false;
while i<=length(a) do if a[i]=b[i-1] then begin
delete(a,i,1);
delete(b,i-1,1);
valtozas:=true;
end else i:=i+1;
if valtozas then ered2:=ered2+1;
i:=2;
valtozas:=false;
while i<=length(b) do if a[i-1]=b[i] then begin
delete(a,i-1,1);
delete(b,i,1);
valtozas:=true;
end else i:=i+1;
if valtozas then ered2:=ered2+1;
ered2:=ered2+length(a);
if ered2<ered1 then ered1:=ered2;
end;
hasonlo:=ered1;
end;
begin
writeln;
writeln('"Computer","Computer"=',hasonlo('Computer','Computer'));
writeln('"Computer","Cmputeer"=',hasonlo('Computer','Cmputeer'));
writeln('"Computer","Kombute"=',hasonlo('Computer','Kombute'));
writeln('"Computer","ootper"=',hasonlo('Computer','ootper'));
writeln('"Computer","Cmpteraa"=',hasonlo('Computer','Cmpteraa'));
writeln('"Computer","Coomputr"=',hasonlo('Computer','Coomputr'));
writeln('"Computer","Compuuteer"=',hasonlo('Computer','Compuuteer'));
end.